package com.ddm.service.impl.webImpl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ddm.constant.MessageConstant;
import com.ddm.entity.webEntity.MarketSp;
import com.ddm.entity.webEntity.Plan;
import com.ddm.entity.webEntity.UserSubscribe;
import com.ddm.exception.DataErrorException;
import com.ddm.mapper.PlanMapper;
import com.ddm.mapper.UserSubscribeMapper;
import com.ddm.result.Result;
import com.ddm.service.webService.PlanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.formula.functions.T;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.time.LocalDate;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 套餐服务实现
 */
@Slf4j
@Service
public class PlanServiceImpl extends ServiceImpl<PlanMapper, Plan> implements PlanService {

    @Resource
    private UserSubscribeMapper userSubscribeMapper;
    @Autowired
    private PlanService planService;
    @Resource
    private PlanMapper planMapper;

    /**
     * 统计每个套餐的订阅次数
     */
    @Override
    public Map<String, Integer> countPlanSubscribes() {
        Map<String, Integer> result = new HashMap<>();
        // 查询所有套餐
        List<Plan> plans = list();
        for (Plan plan : plans) {
            // 统计每个套餐的订阅次数
            QueryWrapper<UserSubscribe> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("plan_id", plan.getId());
            int count = userSubscribeMapper.selectCount(queryWrapper);
            result.put(plan.getPlanName(), count);
        }
        return result;
    }

    @Override
    public boolean updatePlan(Plan plan) {
        // 1. 打印传入的参数（确认修改的内容）
        log.info("开始修改套餐，参数：id={}, planName={}, price={}, durationDay={}",
                plan.getId(), plan.getPlanName(), plan.getPrice(), plan.getDurationDays());

        // 2. 校验参数
        if (plan.getPrice().compareTo(BigDecimal.ZERO) < 0) {
            log.error("价格校验失败：价格不能为负数，传入值={}", plan.getPrice());
            throw new IllegalArgumentException("价格不能为负数");
        }
        if (plan.getDurationDays() <= 0) {
            log.error("时长校验失败：时长不能小于等于0，传入值={}", plan.getDurationDays());
            throw new IllegalArgumentException("套餐时长不能小于等于 0");
        }

        // 3. 执行更新前，查询数据库当前值（用于对比）
        Plan oldPlan = getById(plan.getId());
        if (oldPlan == null) {
            log.error("修改失败：套餐不存在，id={}", plan.getId());
            throw new IllegalArgumentException("套餐不存在");
        }
        log.info("更新前的数据库值：planName={}, price={}, durationDay={}",
                oldPlan.getPlanName(), oldPlan.getPrice(), oldPlan.getDurationDays());

        // 4. 执行更新，并打印返回结果
        boolean updateResult = updateById(plan);
        log.info("updateById 执行结果：{}（true=更新成功，false=无变化或失败）", updateResult);

        // 5. 执行更新后，再次查询数据库（确认是否真的修改）
        Plan newPlan = getById(plan.getId());
        log.info("更新后的数据库值：planName={}, price={}, durationDay={}",
                newPlan.getPlanName(), newPlan.getPrice(), newPlan.getDurationDays());

        // 6. 对比更新前后的关键字段（判断是否真的有变化）
        boolean hasActualChange = !oldPlan.getPlanName().equals(newPlan.getPlanName())
                || oldPlan.getPrice().compareTo(newPlan.getPrice()) != 0
                || !oldPlan.getDurationDays().equals(newPlan.getDurationDays());
        log.info("实际是否有变化：{}", hasActualChange);

        // 7. 基于实际变化返回结果（而非依赖 updateById）
        return hasActualChange;
    }

    /**
     * 列出所有套餐信息
     */
    @Override
    public List<Plan> getAllPlans() {
        // 直接使用MyBatis-Plus的list()方法查询所有套餐
        // 可根据需要添加排序条件
        QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
        queryWrapper.orderByAsc("id"); // 按ID升序排列
        return list(queryWrapper);
    }

    /**
     * 根据套餐Id返回对应套餐信息
     */
    @Override
    public Plan getPlanById(Long planId) {
        // 1. 空值校验：避免传入 null 导致查询异常
        if (planId == null || planId <= 0) {
            log.error("套餐ID非法：{}", planId);
            throw new IllegalArgumentException("套餐ID不能为空或小于0");
        }
        QueryWrapper<Plan> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("id",planId); // 按ID升序排列
        // 3. 执行查询：用 baseMapper.selectOne 查询单条数据（ID 唯一）
        return baseMapper.selectOne(queryWrapper);
    }

    @Override
    public Plan addPlan(Plan plan) {
        // 保存新套餐
        planMapper.insert(plan);
        // 返回保存后的套餐（包含自动生成的ID）
        return planMapper.selectById(plan.getId());
    }

    @Override
    public Result<String> enablePlan(Long planId) {
        if (planId == null || planId <= 0) {
            log.error("套餐ID非法：{}", planId);
            return Result.error("套餐ID不能为空或小于0");
        }
        Plan plan = getPlanById(planId);
        if (plan == null) {
            log.error("启用套餐失败：套餐ID={}不存在", planId);
            return Result.error("套餐ID=%d不存在".formatted(planId));
        }
        if(plan.getStatus()==0){
            log.info("套餐ID={}已经启用，无需重复操作",planId);
            return Result.success("套餐ID=%d已经启用，无需重复操作".formatted(planId));
        }
        Plan newPlan = getById(planId);
        newPlan.setStatus(0);
        updateById(newPlan);
        if(plan.getStatus()!=newPlan.getStatus()){
            log.info("启用套餐成功：套餐ID={}",planId);
        }else {
            log.error("启用套餐失败：套餐ID={}",planId);
            return Result.error("启用套餐ID=%d失败".formatted(planId));
        }
        return Result.success("启用套餐ID=%d成功".formatted(planId));
    }

    /**
     * 检查套餐是否有未到期的用户订阅（根据实际业务实现）
     * @param planId 套餐ID
     * @return true=有未到期订阅，false=无
     */
    private boolean checkHasActiveSubscribers(Long planId) {
        LambdaQueryWrapper<UserSubscribe> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(UserSubscribe::getPlanId, planId);
        //到期时间大于当前时间
        queryWrapper.ge(UserSubscribe::getEndDate, LocalDate.now());
        return userSubscribeMapper.selectCount(queryWrapper) > 0;
    }

    @Override
    public  Result<String> disablePlan(Long planId) {
        if (planId == null || planId <= 0) {
            log.error("套餐ID非法：{}", planId);
            return Result.error("套餐ID不能为空或小于0");
        }
        Plan plan = getPlanById(planId);
        if (plan == null) {
            log.error("禁用套餐失败：套餐ID={}不存在", planId);
            return Result.error("套餐ID=%d不存在".formatted(planId));
        }
        if(plan.getStatus()==1){
            log.info("套餐ID={}已经禁用，无需重复操作",planId);
            return Result.success("套餐ID=%d已经禁用，无需重复操作".formatted(planId));
        }
        boolean hasActiveSubscribers = checkHasActiveSubscribers(planId);
        if (hasActiveSubscribers) {
            log.error("禁用套餐失败：套餐ID={}存在未到期的用户订阅", planId);
            return Result.error("套餐ID=%d存在未到期的用户订阅，不允许禁用".formatted(planId));
        }
        Plan newPlan = getById(planId);
        newPlan.setStatus(1);
        updateById(newPlan);
        if(plan.getStatus()!=newPlan.getStatus()){
            log.info("禁用套餐成功：套餐ID={}",planId);
        }else {
            log.error("禁用套餐失败：套餐ID={}",planId);
            return Result.error("禁用套餐失败，请重试");
        }
        return Result.success("禁用套餐ID=%d成功".formatted(planId));
    }

    @Override
    public Result deletePlan(Long planId) {
        //1.检验参数合理
        if (planId == null || planId <= 0) {
            log.error("套餐ID非法：{}", planId);
            return Result.error("套餐ID不能为空或小于0");
        }
        //2.删除套餐
        Plan plan = getPlanById(planId);
        //若为异常数据抛出异常
        if (plan == null) {
            throw new DataErrorException(MessageConstant.ERROR_DATA);
        }
        boolean hasActiveSubscribers = checkHasActiveSubscribers(planId);
        if (hasActiveSubscribers) {
            log.error("删除套餐失败：套餐ID={}存在未到期的用户订阅", planId);
            return Result.error("套餐ID=%d存在未到期的用户订阅，不允许删除".formatted(planId));
        }
        removeById(planId);
        plan = getPlanById(planId);
        //3.返回结果
        if (plan==null) {
            log.info("删除套餐成功：套餐ID={}", planId);
            return Result.success("删除套餐ID=%d成功".formatted(planId));
        } else {
            log.error("删除套餐执行失败：套餐ID={}，数据库未删除数据", planId);
            return Result.error("删除套餐ID=%d失败".formatted(planId));
        }
    }
}